package com.pyue.eam.regi.service.impl;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.pyue.eam.admin.api.entity.eam.EamHistoryDataEntity;
import com.pyue.eam.admin.service.EamHistoryDataService;
import com.pyue.eam.common.data.resolver.TenantKeyStrResolver;
import com.pyue.eam.regi.bo.MonthPerforEnum;
import com.pyue.eam.regi.mapper.CqTaskLibMapper;
import com.pyue.eam.admin.utils.RedisTemplateUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.YearMonth;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;

@Service
@AllArgsConstructor
public class PerformanceService {
    private final RedisTemplateUtil redisTemplateUtil;
    private final CqTaskLibMapper cqTaskLibMapper;
    private final TenantKeyStrResolver tenantKeyStrResolver;
    private final EamHistoryDataService eamHistoryDataService;
    private static final String REDIS_KEY_PREFIX = "performance_info:";

    /**
     * 存绩效数据
     */
    public void savePerformanceByCode(MonthPerforEnum monthPerforEnum, YearMonth yearMonth) {
        String name = monthPerforEnum.name();
        Number data = monthPerforEnum.getHandler().apply(yearMonth);

        eamHistoryDataService.save(EamHistoryDataEntity.builder()
                .hisTypeBiz(name)
                .multiFlag("0")
                .yearMonthValue(yearMonth)
                .bizData(Convert.toNumber(data, 0))
                .build());
    }

    public List<EamHistoryDataEntity> savePerformanceByDb(String perforCode) {
        List<EamHistoryDataEntity> listByCode = eamHistoryDataService.getListByCode(perforCode);
        listByCode = CollUtil.reverse(listByCode);
        if (CollUtil.isNotEmpty(listByCode)) {
            String key = tenantKeyStrResolver.extract(REDIS_KEY_PREFIX + perforCode, StrUtil.COLON);
            redisTemplateUtil.setListAll(key, listByCode);
        }
        return listByCode;
    }


    /**
     * 取绩效数据
     *
     * @param monthPerforEnum 绩效枚举
     * @param yearMonthList   需要几个月数据
     */
    public List<? extends Number> getPerformanceByCode(MonthPerforEnum monthPerforEnum, List<String> yearMonthList) {
        final String finalPerforCode = monthPerforEnum.name();
        // 最后一个月值
        YearMonth lastMonth = YearMonth.parse(CollUtil.getLast(yearMonthList));
        // 当月重新计算
        Number lastMonthData = monthPerforEnum.getHandler().apply(lastMonth);

        String key = tenantKeyStrResolver.extract(REDIS_KEY_PREFIX + finalPerforCode, StrUtil.COLON);
        List<EamHistoryDataEntity> dataList = (List<EamHistoryDataEntity>) redisTemplateUtil.getAllList(key);

        AtomicBoolean flag = new AtomicBoolean(false);

        Map<String, EamHistoryDataEntity> dataEntityMap = CollStreamUtil.toMap(dataList, e -> e.getYearMonthValue().toString(), Function.identity());
        Map<String, EamHistoryDataEntity> firstDataEntityMap = dataEntityMap;
        yearMonthList.stream().filter(e -> !e.equals(lastMonth.toString())).forEach(e -> {
            if (!firstDataEntityMap.containsKey(e)) {
                flag.set(Boolean.TRUE);
            }
        });

        // 重新缓存数据
        if (CollUtil.isEmpty(dataList) || flag.get()) {
            dataList = eamHistoryDataService.getListByCode(finalPerforCode);
            dataEntityMap = CollStreamUtil.toMap(dataList, e -> e.getYearMonthValue().toString(), Function.identity());
            final Map<String, EamHistoryDataEntity> finalDataEntityMap = dataEntityMap;
            yearMonthList.stream().filter(e -> !e.equals(lastMonth.toString())).forEach(e -> {
                if (!finalDataEntityMap.containsKey(e)) {
                    savePerformanceByCode(monthPerforEnum, YearMonth.parse(e));
                    flag.set(Boolean.TRUE);
                }
            });

            redisTemplateUtil.remove(key);
            dataList = savePerformanceByDb(finalPerforCode);
        }


        dataList.add(EamHistoryDataEntity.builder().yearMonthValue(lastMonth).bizData(Convert.toStr(lastMonthData)).build());

        // 重新缓存数据
        if (flag.get()) {
            // 如果有数据缺失则重新排序入缓存
            redisTemplateUtil.remove(key);
            dataList = savePerformanceByDb(finalPerforCode);
        }

        return CollStreamUtil.toList(dataList, e -> Convert.toNumber(e.getBizData()));
    }


    // 当月发布任务数
    public Integer monthTaskNewCount(YearMonth yearMonth) {
        return cqTaskLibMapper.monthTaskNewCount(yearMonth);
    }

    // 当月接受任务数
    public Integer monthTaskOverCount(YearMonth yearMonth) {
        return cqTaskLibMapper.monthTaskOverCount(yearMonth);
    }

}
